package com.innovate.nms.service.inspect;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.util.StopWatch;

import com.ivan.toolkit.common.Anival;
import com.ivan.toolkit.common.Debug;
import com.ivan.toolkit.common.Events;

import lombok.Getter;
import lombok.extern.log4j.Log4j;

@Log4j
public abstract class InspectTask implements Runnable {
	
	@Getter
	private static ExecutorService executor = Executors.newSingleThreadExecutor();
	
	public static enum State {
		waiting, pending, finished
	}
	
	public static enum Result {
		succeed, failed, unknown
	}
	
	@Getter
	private Anival porperty = new Anival();
	
	@Getter
	private Result result = Result.unknown;
	
	@Getter
	private long cost;
	
	@Getter
	private State state = State.waiting;
	
	public static final String EventKey = "inspect"; 
	
	public InspectTask() {
	}
	
	public String getStateString() {
		switch(state) {
		case pending: return "检测中...";
		case finished: return "完成";
		default:
		case waiting: return "等待中...";
		}
	}
	
	public String getResultString() {
		

		if(state == State.finished) {
			
			switch(result) {
			case succeed: return "成功";
			case failed: return "失败";
			default: return "未知";
			}
			
		} else {
			
			return "";
			
		}
		
	}
	
	public void reset() {
		
		result = Result.unknown;
		
		state = State.waiting;
		fireEvent();
	}	
	
	private void fireEvent() {
		Events event = new Events(EventKey);
		event.put("source", this);
		event.put("class", this.getClass().getSimpleName());
		Events.post(event);		
	}
	
	public abstract String goal();

	protected abstract Result inspect() throws Exception;
	
	public void execute() {
		executor.submit(this);
	}

	@Override
	public void run() {

		try {
			
			state = State.pending;
			fireEvent();
			
			Debug.fire(this.getClass().getSimpleName(), "任务启动: " + goal());
			
			StopWatch sw = new StopWatch();
			sw.start();
			
			result = inspect();
			
			sw.stop();
			
			cost = sw.getTotalTimeMillis();
		
			
		} catch (Exception e) {
			
			log.error("Exception when inspecting", e);
			
		} finally {
			
			state = State.finished;
			fireEvent();
			
			Debug.fire(this.getClass().getSimpleName(), "任务结束: " + goal() + "，结果： " + this.getResultString());
			
		}
		
	}	
	
}
